home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / tvtoys04.zip / VIDEO.PAS < prev    next >
Pascal/Delphi Source File  |  1993-12-10  |  15KB  |  557 lines

  1. (***************************************************************************
  2.   Video unit
  3.   Video mode routines, trial and error legal mode detection
  4.   PJB August 29, 1993, Internet mail to d91-pbr@nada.kth.se
  5.   Copyright 1993, All Rights Reserved
  6.   Free source, use at your own risk.
  7.   If modified, please state so if you pass this around.
  8.  
  9.   Intended for Turbo Vision, easily rehacked.
  10.  
  11.   ■ Use CheckVideoType to initialize before you call any
  12.     other procedures or access any variables in this unit.
  13.  
  14.   ■ Use ScanEVGAModes only on EGA and VGA compatible cards, or else
  15.     the results might be misleading. Check this before you use
  16.     ScanEVGAModes.
  17.  
  18.   If the video card is VERY old, the computer might crash since the
  19.   BIOSes weren't designed to handle "illegal" video modes back then...
  20.  
  21.   For full VESA, Video7 support, use only SetSpecialVideoMode and
  22.   GetSpecialVideoMode from this unit.
  23.  
  24.   You can overlay this unit only if AutoCheckVideoType is not defined.
  25.   See CONFIG.PAS for a description of all conditional defines.
  26.  
  27. ***************************************************************************)
  28. unit Video;
  29.  
  30. {$I toyCfg}
  31.  
  32. {$B-,Q-,S-,X+}
  33. {$IFDEF DPMI} {$G+} {$ENDIF}
  34.  
  35. {$IFNDEF AutoCheckVideoType}
  36.   {$O+}
  37. {$ENDIF}
  38.  
  39.  
  40. interface
  41.  
  42.   uses
  43.    {$IFDEF DPMI}
  44.     DPMI,
  45.     WinAPI,
  46.    {$ENDIF}
  47.    {$IFDEF VesaSupport}
  48.     VESA,
  49.    {$ENDIF}
  50.     Drivers;
  51.  
  52.   type
  53.     AddModeProc = procedure (Mode, Rows, Columns, CharHeight:Word; Color:boolean);
  54.  
  55.  
  56.   (*******************************************************************
  57.     Video BIOS stuff
  58.   *******************************************************************)
  59.   const
  60.     CrtWidth   = $4A; (* byte *)
  61.     CrtSize    = $4C; (* word *)
  62.     Addr6845   = $63; (* word *)
  63.     CrtRows    = $84; (* byte EGA/VGA *)
  64.     CrtPoints  = $85; (* byte EGA/VGA *)
  65.     CrtInfo    = $87; (* byte EGA/VGA *)
  66.  
  67.     (* Use with UseInternalFont *)
  68.     Internal8x8Font  = $12;
  69.     Internal8x14Font = $11;
  70.     Internal8x16Font = $14;
  71.  
  72.  
  73.   (*******************************************************************
  74.     Video mode detection stuff
  75.   *******************************************************************)
  76.   type
  77.     VideoTypes = (Other, EGA, VGA);
  78.     SpecialVideoTypes = set of (vtVesa, vtVideo7);
  79.  
  80.   const
  81.     (* This value can be used to rule out Vesa and V7 tests run-time *)
  82.     VideoTypesToCheck : SpecialVideoTypes = [vtVesa, vtVideo7];
  83.  
  84.   var
  85.     (* Detected video type *)
  86.     VideoType : VideoTypes;
  87.  
  88.  {$IFDEF Video7Support}
  89.     Video7 : boolean;
  90.  
  91.   const
  92.     V7Installed = 1;
  93.     HPInstalled = 2;
  94.  {$ENDIF}
  95.  
  96.   const
  97.    {$IFDEF VesaSupport}
  98.     DontClearVideoModeFlag : Word = $80;
  99.    {$ELSE}
  100.     DontClearVideoModeFlag = $80;
  101.    {$ENDIF}
  102.  
  103.   type
  104.     ModeSet = set of 0..127;
  105.  
  106.   const
  107.     (* 0,1 intentionally left out *)
  108.     StandardTextModes : ModeSet = [2, 3, 7];
  109.     VGAModes          : ModeSet = [2, 3, 7, 8, $14..127];
  110.     VESAModes         : ModeSet = [$8..$C];  (* Corresponds to $108..$10C *)
  111.  
  112.  
  113.   (*******************************************************************
  114.     Video state object
  115.   *******************************************************************)
  116.   type
  117.     VideoState =
  118.       object
  119.         Mode       : Word;
  120.         Lines      : Byte;
  121.         CharHeight : Byte;
  122.         procedure Save;
  123.         procedure Restore;
  124.       end;
  125.  
  126.  
  127.   procedure SetSpecialVideoMode(Mode:Word);
  128.   function  GetSpecialVideoMode:Word;
  129.  
  130.  {$IFDEF VesaSupport}
  131.   procedure CheckVesa;
  132.  {$ENDIF}
  133.  {$IFDEF Video7Support}
  134.   procedure CheckVideo7;
  135.  {$ENDIF}
  136.   procedure CheckEVGA;
  137.   procedure CheckVideoType;
  138.  
  139.   function  GetCurrentScanLines:Integer;
  140.   procedure UseInternalFont(Font:Byte);
  141.   procedure LoadUserFont(Points:Byte; First, Count:Integer; Font:Pointer);   function  IsProbablyTextMode:Boolean;
  142.   function  IsColorMode:Boolean;
  143.  
  144.   procedure ScanEVGAModes(ModeOffset:Word; const ModesToCheck:ModeSet; AddMode:AddModeProc);
  145.  
  146. (***************************************************************************
  147. ***************************************************************************)
  148. implementation
  149.  
  150.  
  151.  {$IFDEF Video7Support}
  152.   (*******************************************************************
  153.     Test for the presence of a Video7 or HP video card
  154.   *******************************************************************)
  155.   function V7orHPInstalled:Byte; assembler;
  156.   asm
  157.       mov  ax,6F00h
  158.       xor  bx,bx
  159.       int  10h
  160.  
  161.       mov  al,V7Installed
  162.       cmp  bx,'V7'
  163.       je   @Fin
  164.  
  165.       mov  al,HPInstalled
  166.       cmp  bx,'HP'
  167.       je   @Fin
  168.  
  169.       mov  al,0
  170.     @Fin:
  171.   end;
  172.  {$ENDIF}
  173.  
  174.  
  175.   (*******************************************************************
  176.     Set video mode using VESA, Video7 or BIOS, if supported and present
  177.   *******************************************************************)
  178.   procedure SetSpecialVideoMode(Mode:Word); assembler;
  179.   asm
  180.       mov  ax,Mode
  181.  
  182.      {$IFDEF VesaSupport}
  183.       cmp  VESA.VesaVersion,0
  184.       je   @NoVesa
  185.       push ax
  186.       call VESA.SetVesaMode
  187.       cmp  al,4Fh                (* Supported? *)
  188.       je   @Fin
  189.  
  190.       mov  bx,Mode
  191.       test bh,7Fh
  192.       jne  @Fin
  193.  
  194.       mov  al,bh
  195.       and  al,80h
  196.       or   al,bl
  197.     @NoVesa:
  198.      {$ENDIF}
  199.  
  200.      {$IFDEF Video7Support}
  201.       cmp  Video7,False
  202.       je   @Go
  203.       mov  bl,al
  204.       mov  ax,6F05h
  205.      {$ENDIF}
  206.  
  207.     @Go:
  208.       int  10h
  209.  
  210.     @Fin:
  211.   end;
  212.  
  213.  
  214.   (*******************************************************************
  215.     Retrieve current video from VESA, Video7 or plain BIOS
  216.   *******************************************************************)
  217.   function GetSpecialVideoMode:Word; assembler;
  218.   asm
  219.      {$IFDEF VesaSupport}
  220.       cmp  VESA.VesaVersion,0
  221.       je   @NoVesa
  222.       call VESA.GetVesaMode
  223.       and  ah,7Fh
  224.  
  225.       {$IFDEF V7UniVesaKludge}
  226.        {$IFDEF Video7Support}
  227.         cmp  Video7,False
  228.         je   @NoV7Test
  229.        {$ENDIF}
  230.        cmp  ax,1         (* Boring bad VESA driver returns this on V7 *)
  231.        je   @NoVesa
  232.      @NoV7Test:
  233.       {$ENDIF}
  234.  
  235.       cmp  bx,4Fh                 (* Success? *)
  236.       je   @Fin
  237.     @NoVesa:
  238.      {$ENDIF}
  239.  
  240.      {$IFDEF Video7Support}
  241.       cmp  Video7,False
  242.       je   @NoV7
  243.  
  244.       mov  ax,6F04h
  245.       int  10h
  246.  
  247.       jmp  @ClearAH
  248.      {$ENDIF}
  249.  
  250.     @NoV7:
  251.       mov  ah,0Fh
  252.       int  10h
  253.  
  254.     @ClearAH:
  255.       and  ax,7Fh
  256.  
  257.     @Fin:
  258.   end;
  259.  
  260.  
  261.   (*******************************************************************
  262.     Vesa present?
  263.   *******************************************************************)
  264.  {$IFDEF VesaSupport}
  265.   procedure CheckVesa; assembler;
  266.   asm
  267.       call DetectVesaVersion
  268.       cmp  VesaVersion,0
  269.       je   @NoVesa
  270.       mov  DontClearVideoModeFlag,8000h
  271.     @NoVesa:
  272.   end;
  273.  {$ENDIF}
  274.  
  275.  
  276.   (*******************************************************************
  277.     Video 7 card?
  278.   *******************************************************************)
  279.  {$IFDEF Video7Support}
  280.   procedure CheckVideo7; assembler;
  281.   asm
  282.       call V7orHPInstalled
  283.       cmp  al,0
  284.       je   @NoV7
  285.       mov  al,1
  286.     @NoV7:
  287.       mov  Video7,al
  288.   end;
  289.  {$ENDIF}
  290.  
  291.  
  292.   (*******************************************************************
  293.     EGA, VGA or Other?
  294.   *******************************************************************)
  295.   procedure CheckEVGA; assembler;
  296.   asm
  297.       push bp
  298.  
  299.       mov  VideoType,Other
  300.       mov  ax,1200h
  301.       mov  bx,10h
  302.       mov  cx,0FFFFh
  303.       int  10h
  304.  
  305.       inc  cx
  306.       je   @Fin               (* No EGA support *)
  307.  
  308.       mov  VideoType,EGA
  309.  
  310.       mov  ax,1A00h
  311.       int  10h
  312.       cmp  al,1Ah
  313.       jne  @Fin               (* Not a VGA or PS/2 type card *)
  314.  
  315.       cmp  bl,7
  316.       jae  @VGA               (* VGA, MCGA *)
  317.  
  318.       cmp  bl,4               (* EGA *)
  319.       jae  @Fin
  320.  
  321.       mov  VideoType,Other    (* Something else *)
  322.       jmp  @Fin
  323.  
  324.     @VGA:
  325.       mov  VideoType,VGA
  326.  
  327.     @Fin:
  328.       pop  bp
  329.   end;
  330.  
  331.  
  332.   (*******************************************************************
  333.     Check which of VESA, Video7, VGA and EGA are present
  334.   *******************************************************************)
  335.   procedure CheckVideoType;
  336.   begin
  337.    {$IFDEF VesaSupport}
  338.     if vtVesa in VideoTypesToCheck then
  339.       CheckVesa;
  340.    {$ENDIF}
  341.    {$IFDEF Video7Support}
  342.     if vtVideo7 in VideoTypesToCheck then
  343.       CheckVideo7;
  344.    {$ENDIF}
  345.     CheckEVGA;
  346.   end;
  347.  
  348.  
  349.   (*******************************************************************
  350.     Calculate the video mode's number of scan lines
  351.   *******************************************************************)
  352.   function GetCurrentScanLines:Integer; assembler;
  353.   asm
  354.       mov  es,Seg0040
  355.  
  356.       mov  al,es:[CrtPoints]
  357.       mov  ah,es:[CrtRows]
  358.       inc  ah
  359.  
  360.       mul  ah
  361.   end;
  362.  
  363.  
  364.   (*******************************************************************
  365.      Change to another font on the video card
  366.      Available fonts are:
  367.        8x8:  EGA, VGA         (Internal8x8Font)
  368.        8x14: EGA, VGA         (Internal8x14Font)
  369.        8x16:      VGA         (Internal8x16Font)
  370.   *******************************************************************)
  371.   procedure UseInternalFont(Font:Byte); assembler;
  372.   asm
  373.       push bp
  374.       mov  ah,11h
  375.       mov  al,Font
  376.       mov  bl,0
  377.       int  10h
  378.       pop  bp
  379.   end;
  380.  
  381.  
  382.   (*******************************************************************
  383.     Define your own characters
  384.     Points: Character height
  385.     First: First char to define
  386.     Count: Chars to define
  387.     Font points to an array of character bitmaps,
  388.     ASCII <First> first, <Points> bytes per char, top to bottom.
  389.   *******************************************************************)
  390.   procedure LoadUserFont(Points:Byte; First, Count:Integer; Font:Pointer);
  391.  {$IFNDEF DPMI}
  392.    assembler;
  393.  {$ELSE}
  394.     var
  395.       Real, Protected : Pointer;
  396.   begin
  397.     if GetDosMem(Real, Protected, Points*Count) then
  398.     begin
  399.       Move(Font^, Protected^, Points*Count);
  400.  {$ENDIF}
  401.       asm
  402.         push bp
  403.         mov  ax,1110h
  404.         mov  bl,0                 { First definition block }
  405.         mov  bh,Points
  406.         mov  cx,Count
  407.         mov  dx,First
  408.        {$IFDEF DPMI}
  409.         mov  RealRegs.RealEBP.Word,0
  410.  
  411.         mov  si,Real.Word+2
  412.         mov  RealRegs.RealES.Word,si
  413.  
  414.         push 10h
  415.         call RealModeInterrupt
  416.        {$ELSE}
  417.         les  bp,Font
  418.         int  10h
  419.        {$ENDIF}
  420.         pop  bp
  421.       end;
  422.  {$IFDEF DPMI}
  423.       GlobalDOSFree(Seg(Protected^));
  424.     end;
  425.   end;
  426.  {$ENDIF}
  427.  
  428.  
  429.   (*******************************************************************
  430.     Turn the display OFF
  431.   *******************************************************************)
  432.   procedure NoRefresh; assembler;
  433.   asm
  434.       cli
  435.       mov    es,Seg0040
  436.       mov    dx,es:[Addr6845]
  437.       add    dx,0006h
  438.  
  439.       in     al,dx
  440.       mov    bx,dx
  441.       mov    dx,03C0h
  442.       mov    al,12h
  443.       out    dx,al
  444.       jmp    @1
  445.     @1:
  446.       xor    al,al
  447.       out    dx,al
  448.       xchg   dx,bx
  449.       in     al,dx
  450.       xchg   dx,bx
  451.  
  452.       mov    al,20h
  453.       out    dx,al
  454.       sti
  455.   end;
  456.  
  457.     
  458.   (*******************************************************************
  459.     Test to see if we're in text mode.
  460.     NB: Turbo Vision supports a maximum of 132 columns (see the
  461.     definitions of TDrawBuffer/MaxViewWidth)
  462.   *******************************************************************)
  463.   function IsProbablyTextMode:Boolean;
  464.   begin
  465.     IsProbablyTextMode:=
  466.       (Mem[Seg0040:CrtWidth]>=40) and (Mem[Seg0040:CrtWidth]<=132) and
  467.       (Mem[Seg0040:CrtRows]>20) and (Mem[Seg0040:CrtRows]<100) and
  468.       (MemW[Seg0040:CrtSize]<>0) and
  469.       (Mem[Seg0040:CrtWidth]*Mem[Seg0040:CrtRows]*4>MemW[Seg0040:CrtSize]);
  470.   end;
  471.  
  472.  
  473.   (*******************************************************************
  474.     This function is used to determine if the video memory segment
  475.     starts at B000 (mono) or B800 (color).
  476.   *******************************************************************)
  477.   function IsColorMode:Boolean;
  478.   begin
  479.     IsColorMode:=MemW[Seg0040:Addr6845]=$03D4;
  480.   end;
  481.  
  482.  
  483.   (*******************************************************************
  484.     procedure ScanEVGAModes(First:byte; AddMode:AddModeProc);
  485.       First:   First video mode to try
  486.       AddMode: Procedure to call for each valid text video mode.
  487.  
  488.       ScanEVGAModes attempts to find out what video modes are available.
  489.       It tries to set every video mode possible, checking to see if
  490.       the BIOS put valid data for a text mode in the BIOS data segment.
  491.       ScanVideoModes starts at mode First and works its way up to mode
  492.       127. Every time a valid Text video mode is found, AddMode is called.
  493.  
  494.       ■ AddMode must be a FAR procedure of the type AddModeProc.
  495.  
  496.   *******************************************************************)
  497.   procedure ScanEVGAModes(ModeOffset:Word; const ModesToCheck:ModeSet; AddMode:AddModeProc);
  498.     var
  499.       Mode : Word;
  500.       Rows, Columns : Word;
  501.   begin
  502.     for Mode:=0 to 127 do
  503.       if Mode in ModesToCheck then
  504.       begin
  505.         SetSpecialVideoMode(ModeOffset+Mode or DontClearVideoModeFlag);
  506.         NoRefresh;
  507.  
  508.         Rows:=Mem[Seg0040:CrtRows]+1;
  509.         Columns:=Mem[Seg0040:CrtWidth];
  510.         if IsProbablyTextMode and (ModeOffset+Mode=GetSpecialVideoMode) then
  511.           AddMode(ModeOffset+Mode, Rows, Columns,
  512.                   Mem[Seg0040:CrtPoints], IsColorMode);
  513.       end;
  514.     end;
  515.  
  516.  
  517. (***************************************************************************
  518.   Video state object
  519. ***************************************************************************)
  520.  
  521.   (*******************************************************************
  522.     Attempt to save current video state
  523.   *******************************************************************)
  524.   procedure VideoState.Save;
  525.   begin
  526.     Mode:=GetSpecialVideoMode;
  527.     Lines:=Mem[Seg0040:CrtRows];
  528.     CharHeight:=Mem[Seg0040:CrtPoints];
  529.   end;
  530.  
  531.  
  532.   (*******************************************************************
  533.     Attempt to restore previous video state
  534.   *******************************************************************)
  535.   procedure VideoState.Restore;
  536.   begin
  537.     SetSpecialVideoMode(Mode);
  538.  
  539.     if Lines<>Mem[Seg0040:CrtRows] then
  540.       case CharHeight of
  541.         14: UseInternalFont(Internal8x14Font);
  542.         16: UseInternalFont(Internal8x16Font);
  543.         else
  544.           UseInternalFont(Internal8x8Font);
  545.       end;
  546.   end;
  547.  
  548.  
  549.     (*******************************************************************
  550.     *******************************************************************)
  551.  
  552. {$IFDEF AutoCheckVideoType}
  553. begin
  554.   CheckVideoType;
  555. {$ENDIF}
  556. end.
  557.